package com.hotel.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hotel.entity.ShoppingCar;
import com.hotel.context.BaseContext;
import com.hotel.dto.ShoppingCarDTO;
import com.hotel.exception.BaseException;
import com.hotel.mapper.ShoppingMapper;
import com.hotel.service.ShoppingService;
import com.hotel.vo.ShoppingVo;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

@Service
@Slf4j
public class ShoppingServiceImpl extends ServiceImpl<ShoppingMapper, ShoppingCar> implements ShoppingService {
    
    @Autowired
    private RedisTemplate<String,Object> redisTemplate;

    private static final String SHOPPING_KEY = "shopping:";



    @Override
    public List<ShoppingVo> getAll() {
        Long currentId = BaseContext.getCurrentId();
       // 从redis中获取数据
        return getAllProduct(currentId);
    }

    @Override
    public List<ShoppingVo> add(ShoppingCarDTO shopping) {
        Long currentId = BaseContext.getCurrentId();
        // 创建shoppingCar对象
        ShoppingCar shoppingCar = new ShoppingCar();
        BeanUtils.copyProperties(shopping, shoppingCar);
        log.info("添加购物车{}",shoppingCar);

        //强制使用当前用户的id
        shoppingCar.setUserId(currentId);

        // 获取当前商品在购物车中的数据
        ShoppingCar existingItem = (ShoppingCar) redisTemplate.opsForHash()
                .get(SHOPPING_KEY + shoppingCar.getUserId(), shoppingCar.getProductId());

        if (existingItem != null) {
            // 增加数量
            shoppingCar.setProductNum(existingItem.getProductNum() + 1);
            //更新总价
            shoppingCar.setAmount(shoppingCar.getAmount().add(shoppingCar.getPrice()));
        } else {
            shoppingCar.setProductNum(1);
            shoppingCar.setAmount(shoppingCar.getPrice());
        }

        // 更新Redis中的数据
        update(shoppingCar);

        // 返回整个购物车的所有商品
        return getAllProduct(shoppingCar.getUserId());
    }

    @Override
    public List<ShoppingVo> sub(ShoppingCarDTO shopping) {
        Long currentId = BaseContext.getCurrentId();
        // 创建shoppingCar对象
        ShoppingCar shoppingCar = new ShoppingCar();
        BeanUtils.copyProperties(shopping, shoppingCar);

        //强制使用当前用户的id
        shoppingCar.setUserId(currentId);

        // 获取当前商品在购物车中的数据
        ShoppingCar existingItem = (ShoppingCar) redisTemplate.opsForHash()
                .get(SHOPPING_KEY + shoppingCar.getUserId(), shoppingCar.getProductId());

        if (existingItem != null) {
            if (existingItem.getProductNum() <= 1) {
                // 删除购物车中的商品
                redisTemplate.opsForHash().delete(SHOPPING_KEY + shoppingCar.getUserId(), shoppingCar.getProductId());
                return getAllProduct(shoppingCar.getUserId());
            }
            // 减少 数量
            shoppingCar.setProductNum(existingItem.getProductNum() - 1);
            //更新总价
            shoppingCar.setAmount(shoppingCar.getAmount().subtract(shoppingCar.getPrice()));
            update(shoppingCar);
        }
        // 返回整个购物车所有商品
        return getAllProduct(shoppingCar.getUserId());

    }

    @Override
    public List<ShoppingVo> deleteAll(Long userId) {
        Long currentId = BaseContext.getCurrentId();
        log.info("用户请求ID{}",userId);
        log.info("当前用户ID{}",currentId);
        if (!userId.equals(currentId)){
            throw new BaseException("不能删除别人的购物车");
        }
        redisTemplate.delete(SHOPPING_KEY + currentId);
        return getAllProduct(currentId);
    }

    private void update(ShoppingCar shoppingCar) {
        // 更新Redis中的数据
        redisTemplate.opsForHash().put(
                SHOPPING_KEY + shoppingCar.getUserId(),
                shoppingCar.getProductId(),
                shoppingCar
        );
    }

    @NotNull
    private List<ShoppingVo> getAllProduct(Long shoppingCar) {
        // 返回整个购物车的所有商品
        List<Object> allItems = redisTemplate.opsForHash()
                .values(SHOPPING_KEY + shoppingCar);
        return allItems.stream()
                .map(item -> {
                    ShoppingVo vo = new ShoppingVo();
                    BeanUtils.copyProperties(item, vo);
                    return vo;
                }).collect(Collectors.toList());
    }
}

